<template>
  <base-modal :title="$t('common.base.bulkEdit')" @closed="reset" :show.sync="visible" width="500px" class="batch-editing-customer-dialog">

    <batch-form :fields="fields" ref="batchForm" :default-address="config.defaultAddress"/>

    <div slot="footer" class="dialog-footer">
      <el-button @click="visible = false">{{ $t('common.base.cancel') }}</el-button>
      <el-button type="primary" @click="onSubmit" :loading="pending">{{ $t('common.base.confirm') }}</el-button>
    </div>
  </base-modal>
</template>

<script>

import { FormFieldMap, } from "@src/component/form/components";
import * as Utils from "@src/component/form/util";
import { editBatchProduct } from "@src/api/ProductApi";
import FormItem from "@src/component/form/FormItem.vue";
import * as CustomerApi from "@src/api/CustomerApi";

import { baseDistValueToObject, searchAddressObjectParams} from '@src/util/addressUtil';
import { formatAddress, useFormTimezone } from 'pub-bbx-utils';

const { disposeFormSubmitTime } = useFormTimezone()

export default {
  name: "batch-editing-dialog",
  props: {
    config: {
      type: Object,
      default: () => ({})
    },
    selectedIds: {
      type: Array,
      default: () => ([])
    },
    callback: Function,
    selectList:{
      type: Array,
      default: () => [],
    }
  },
  data: () => {
    return {
      visible: false,
      pending: false,
    }
  },
  computed: {
    fields() {
      let tv = null;
      let formTypes = ["attachment", "separator", "location", "info", "autograph", "formula", "related_task",'richtext'];
      let fieldNames = ["createUser", "createTime", "updateTime", "productTemplate", "tags", "remindCount", "qrcodeId", "linkmanName", "phone", "address"];
      let isNotModify = ["text", "textarea", "number"];
      let isRepeat = ["text", "textarea", "number", "phone"];

      let fields = (this.config.fields || [])
        .filter(f => formTypes.indexOf(f.formType) < 0 && !fieldNames.some(key => key === f.fieldName))
        .filter(f => !(isNotModify.indexOf(f.formType) > -1 && f.setting?.defaultValueConfig && !!f.setting?.defaultValueConfig.isNotModify))
        .filter(f => !(isRepeat.indexOf(f.formType) > -1 && f.setting?.isRepeat == 1))
        .map(f => {
          tv = Object.assign({}, f);

          if (tv.formType === "select") { 
            if(tv.setting.selectType == 2){ 
              tv.setting.selectType = 1
            }          
          }
          
          if (tv.isSystem) {
            tv.orderId -= 100;
          }
          
          // 产品状态批量编辑单选 - 不明白高级搜索为啥要多选，用的同一份数据
          if (tv.fieldName == 'productStatus') {
            tv.setting.isMulti = false;
          }
          // tv.isNull = 0;
          return Object.freeze(tv);
        });

      if (!fields || !fields.length) return [];
      return fields.sort((a, b) => a.orderId - b.orderId);
    },
    productTypes() {
      return this.config.productTypes || [];
    }
  },
  mounted() {
    this.$el.addEventListener("form.add.field", this.addFieldHandler);
  },
  beforeDestroy() {
    this.$el.removeEventListener("form.add.field", this.addFieldHandler);
  },
  methods: {
    addFieldHandler(event) {
      this.validate = event.detail.validate;
    },
    async onSubmit() {
      try {
        if (await this.validate()) return;
      

        const params = this.buildParams();
        let idNumber = 0;
        try {
          idNumber = params.ids.split(",").length;
        } catch (error) {
          console.warn(error, "error try catch");
        }

        await Utils.bgiPrivateVerification(this.selectList, 
          { AddressKey: 'address', CountryKey: 'country', formType: params.formType })


        this.pending = true;

        editBatchProduct(params)
          .then(res => {
            setTimeout(() => {

              // es同步延迟
              const failure = res.status;

              this.pending = false;
              this.$platform.notification({
                type: !failure ? "success" : "error",
                title: !failure ? this.$t('product.list.tips.editProductTip1') : this.$t('product.list.tips.editProductTip2'),
                message: !failure ? null : res.message
              });

              if (failure) return;
              this.visible = false;
              // this.reset();
              this.callback && this.callback();
            }, idNumber > 20 ? 3000 : 1500);
          })
          .catch(e => console.error("e", e));
      } catch (error) {

      }
    },
    reset() {
      this.$refs.batchForm.reset();
      this.$refs.batchForm.buildForm();
    },
    open() {

      if (!this.selectedIds.length) {
        return this.$platform.alert(this.$t('product.list.tips.editProductTip3'));
      }

      this.reset();
      this.visible = true;
    },
    buildParams() {
      let tv = null;
      const {form, selectedField: sf} = this.$refs.batchForm.returnData()

      // 处理国际化时间转换
      const value = disposeFormSubmitTime([sf], form)
      let params = {
        mapJson: JSON.stringify({
          [sf.fieldName]: value[sf.fieldName]
        }),
        ids: this.selectedIds.join(","),
        formType: sf.formType
      };

      if (this.selectedFieldName === "tags") {
        params.mapJson = JSON.stringify({
          [sf.fieldName]: form[sf.fieldName].map(({id, tagName}) => ({id, tagName}))
        })
      }
      // if (sf.formType === 'user') {
      //   tv = form[sf.fieldName];

      //   params.mapJson = JSON.stringify({
      //     [sf.fieldName]: {
      //       userId: tv.userId,
      //       displayName: tv.displayName,
      //       staffId: tv.staffId
      //     },
      //   })
      // }
      if (sf.fieldName === "manager" || sf.fieldName === "productManager") {
        tv = form[sf.fieldName];

        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            id: tv.userId,
            name: tv.displayName,
            staffId: tv.staffId
          },
        })
      }

      if (sf.formType === "related_catalog") {
        tv = form[sf.fieldName].id;
        params.mapJson = JSON.stringify({
          [sf.fieldName]: tv,
        })
      }

      if (sf.formType === "address") {
        tv = form[sf.fieldName];

        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            ...tv,
            all: formatAddress(tv,'')
          },
        })
      }

      return params;
    },

  },
  components: {
    BatchForm: {
      name: "batch-form",
      props: {
        fields: {
          type: Array,
          default: () => ([])
        },
        defaultAddress: {
          type: Array,
          default: () => ([])
        }
      },
      data:() => {
        return {
          selectedField: {},
          form: {},
          inputRemoteSearch: {
            customer: {
              options: [],
              loading: false,
            },
          },
        }
      },
      mounted() {
        this.buildForm();
      },
      computed: {
        // 是否为质保开始实际、质保结束时间
        isQualityInfoTime() {
          return ['qualityInfoStartTime', 'qualityInfoEndTime'].includes(this.selectedField?.fieldName);
        }
      },
      methods: {
        returnData() {
          return {
            selectedField: this.selectedField,
            form: Object.assign({}, this.form),
          }
        },
        reset() {
          this.form = {};
          if(this.fields.length == 0) {
            return;
          }
          this.selectField(this.fields[0].fieldName)
        },
        dispatch({type, bubbles = false, params = {}}) {
          // const _dom = Array.prototype.slice.call(this.$el.children)
          //   .filter(d => /form-item/g.test(d.className))[0];
          this.$refs.editForm.$el.dispatchEvent(new CustomEvent(type, {detail: params, bubbles}));
        },
        buildForm() {
          if (Object.keys(this.form).length === this.fields.length) return;
          this.form = Utils.initialize(this.fields);
        },
        update(event) {
          /**
           * 选择团队使用的是单独的组件，不是统一的form组件，所以更新时的返回值不同，需要特殊处理
          */
          if (this.selectedField.fieldName === "customer") {
            this.form[this.selectedField.fieldName] = event;
            return
          }

          const f = event.field;
          this.form[f.fieldName] = event.newValue;
        },
        searchCustomer(keyword) {
          this.inputRemoteSearch.customer.loading = true;
          CustomerApi.getCustomerListAsyn({keyword, pageNum: 1, })
            .then(res => {
              this.inputRemoteSearch.customer.options = res.list;
              this.inputRemoteSearch.customer.loading = false;
            })
            .catch(err => console.error("searchCustomerManager function catch err", err));
        },
        selectField(val) {
          this.selectedField = this.fields.filter(f => f.fieldName === val)[0];

          /**
             * 1、切换的字段是系统地址时，根据默认值设置
             * 2、切换字段的时候，重新注册一遍，是因为： 切换前后两个字段类型相同，不会触发字段的组件的重新注册，form-item 的 field 就不会更新，还是切换之前的 field
             */

          if (this.selectedField.formType === "address" && this.selectedField.isSystem) {
            const address = baseDistValueToObject(this.defaultAddress);

            this.form[this.selectedField.fieldName] = {
              ...(searchAddressObjectParams(address))
            }
          }

          this.dispatch({
            type: "form.add.field",
            params: {
              value: () => this.form[this.selectedField.fieldName],
              field: this.selectedField,
              fieldName: this.selectedField.fieldName
            }
          })

          this.dispatch({
            type: "form.clear.validate",
          })
        },
        renderSelector() {
          if (!this.fields) return null;
          return (
            <div>
            <el-select value={this.selectedField.fieldName} placeholder={this.$t('product.list.tips.editProductTip4')} onChange={this.selectField}>
              {this.fields.map(f => (
                <el-option
                  key={f.fieldName}
                  label={f.displayName}
                  value={f.fieldName}>
                </el-option>
              ))}
            </el-select>
            { this.isQualityInfoTime && <p class="quality-date-tip">{this.$t('product.list.tips.editProductTip5')}</p> }
            </div>
          )
        },

        renderInput(h) {
          const sf = this.selectedField;

          if (!sf.formType) return null;

          if (sf.fieldName === "customer") {
            return h(
              "el-select",
              {
                props: {
                  filterable: true,
                  remote: true,
                  clearable: true,
                  "remote-method": this.searchCustomer,
                  value: this.form[sf.fieldName],
                  loading: this.inputRemoteSearch.customer.loading,
                  placeholder: this.$t('common.base.inputKeywordToSearch'),
                },
                on: {
                  input: event => {
                    this.update(event)
                    this.$forceUpdate()
                  }
                }
              },
              this.inputRemoteSearch.customer.options
                .map(op => (
                  h(
                    "el-option",
                    {
                      props: {
                        key: op.id,
                        label: op.name,
                        value: op.id,
                      }
                    }
                  )
                )),
            )
          }

          const comp = FormFieldMap.get(sf.formType);
          const data = {
            props: {
              field: sf,
              value: this.form[sf.fieldName],
              placeholder: Utils.genPlaceholder(sf),
            },
            on: {
              update: event => this.update(event)
            }
          };

          // if (sf.formType === 'address' && !sf.isSystem) {
          //   data.props.disableMap = true;
          // }

          return h(comp.build, data);
        }
      },
      render(h) {
        return (
          <div>
            <div class="item">
              <label class="form-name">{this.$t('product.modifyField')}</label>
              <div>{this.renderSelector()}</div>
            </div>
            <form-item ref="editForm" label={this.$t('product.list.modifyTo')}>
              {this.renderInput(h)}
            </form-item>
          </div>
        )
      }
    },
    components: {
      [FormItem.name]: FormItem,
    }
  }

}
</script>

<style lang="scss">

  .batch-editing-customer-dialog {

    .base-modal-body {
      padding: 10px 30px 0;
    }

    .form-name, .form-item label {
      width: 70px;
      padding: 0;
      line-height: 32px;
    }

    .el-select {
      width: 100%;
    }

    .item {
      display: flex;
      justify-content: space-between;
      line-height: 32px;
      div {
        flex-grow: 1;
        .el-select {
          width: 100%;
        }

        .quality-date-tip {
          color: $text-color-secondary;
          font-size: 12px;
          margin: 0;
          height: 15px;
          margin-top: -6px;
        }
      }
    }

    .dialog-footer {
      display: flex;
      justify-content: flex-end;
    }

  }

</style>